package com.example.annotationdemo.aop;

import com.example.annotationdemo.annotation.BusinessAnnotation;
import com.example.annotationdemo.stategy.BusinessStrategyContext;
import jakarta.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * @author kw
 * @program annotation-demo
 * @description
 * @create 2024 - 05 - 19 16:18
 **/

@Aspect
@Component
public class BusinessAspect {

    @Resource
    private BusinessStrategyContext businessStrategyContext;

    /**
     * 类拦截器：@within
     * 方法拦截器：@annotation
     */
    @Pointcut(value = "@within(com.example.annotationdemo.annotation.BusinessAnnotation)" +
            "|| @annotation(com.example.annotationdemo.annotation.BusinessAnnotation)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object process(ProceedingJoinPoint pjp) {
        Object proceed;
        try {
            MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
            BusinessAnnotation annotation = methodSignature.getMethod().getAnnotation(BusinessAnnotation.class);
            if (annotation != null && annotation.open()) {
                businessStrategyContext.handleBusiness(pjp, annotation.businessType().getValue());
            } else {
                annotation = pjp.getTarget().getClass().getAnnotation(BusinessAnnotation.class);
                if (annotation != null && annotation.open()) {
                    businessStrategyContext.handleBusiness(pjp, annotation.businessType().getValue());
                }
            }
            proceed = pjp.proceed();

        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        return proceed;
    }
}
